package utils

import (
	"game-server/interfaces"
	"log"
	"sync"
)

// WorkerPool 工作池管理器
type WorkerPool struct {
	workerCount int
	jobs        chan interfaces.IClient
	wg          sync.WaitGroup
	stopCh      chan struct{}
}

// NewWorkerPool 创建一个新的工作池
func NewWorkerPool(workerCount int) *WorkerPool {
	pool := &WorkerPool{
		workerCount: workerCount,
		jobs:        make(chan interfaces.IClient, workerCount*2), // 缓冲区大小为工作协程数的2倍
		stopCh:      make(chan struct{}),
		wg:          sync.WaitGroup{},
	}

	// 启动工作协程
	pool.Start()

	return pool
}

// Start 启动所有工作协程
func (p *WorkerPool) Start() {
	for i := 0; i < p.workerCount; i++ {
		p.wg.Add(1)
		go p.worker(i)
	}
	log.Printf("工作池已启动，工作协程数量: %d", p.workerCount)
}

// worker 工作协程
func (p *WorkerPool) worker(id int) {
	defer p.wg.Done()

	log.Printf("工作协程 %d 已启动", id)

	for {
		select {
		case client, ok := <-p.jobs:
			if !ok {
				log.Printf("工作协程 %d 关闭中: 任务通道已关闭", id)
				return
			}
			// 处理客户端的读写操作
			log.Printf("工作协程 %d 接收到客户端 %s (ID: %d)", id, client.GetUsername(), client.GetID())

			// 创建读写协程
			go client.ReadPump()
			go client.WritePump()

		case <-p.stopCh:
			log.Printf("工作协程 %d 收到停止信号", id)
			return
		}
	}
}

// Submit 提交新的客户端到工作池
func (p *WorkerPool) Submit(client interfaces.IClient) {
	select {
	case p.jobs <- client:
		log.Printf("客户端 %s (ID: %d) 已提交到工作池", client.GetUsername(), client.GetID())
	default:
		// 如果任务队列已满，直接处理
		log.Printf("工作池任务队列已满，直接处理客户端 %s (ID: %d)", client.GetUsername(), client.GetID())
		go client.ReadPump()
		go client.WritePump()
	}
}

// Stop 停止工作池
func (p *WorkerPool) Stop() {
	log.Println("工作池停止中...")
	close(p.stopCh) // 发送停止信号给所有工作协程
	close(p.jobs)   // 关闭任务通道
}

// Wait 等待所有工作协程退出
func (p *WorkerPool) Wait() {
	p.wg.Wait()
	log.Println("工作池已停止，所有工作协程已退出")
}

// Close 关闭工作池并等待所有工作协程退出
func (p *WorkerPool) Close() {
	p.Stop()
	p.Wait()
}
